#include"StringPool.h"
#include"variable.h"
#include<iostream>
#include"DependencyInstance.h"
using namespace std;

void DependencyInstance::init(){
	fv = NULL;
	actParserTree = NULL;
	forms = NULL;
	lemmas = NULL;
	cpostags = NULL;
	postags = NULL;
	feats = NULL;
	heads = NULL;
	deprels = NULL;
	relFeats = NULL;
}

DependencyInstance::DependencyInstance(){
	init();
	forms = new vector<string*>();
	lemmas = new vector<string*>();
	cpostags = new vector<string*>();
	postags = new vector<string*>();
	heads = new vector<int>();
	deprels = new vector<string*>();
	feats = new vector<vector<string*>*>();
}

DependencyInstance::DependencyInstance(std::vector<string*> *forms, std::vector<string*> *postags, std::vector<string*> *labs, std::vector<int> *heads){
	init();
	this->forms = forms;
	this->postags = postags;
	this->deprels = labs;
	this->heads = heads;
}

DependencyInstance::DependencyInstance(std::vector<string*> *forms, std::vector<string*> *lemmas, std::vector<string*> *cpostags, std::vector<string*> *postags, std::vector<string*> *labs, std::vector<vector<string*>*> *feats, std::vector<int> *heads){
	init();
	this->forms = forms;
	this->postags = postags;
	this->deprels = labs;
	this->heads = heads;
	this->lemmas = lemmas;
	this->cpostags = cpostags;
	this->feats = feats;
}

DependencyInstance::DependencyInstance(std::vector<string*> *forms, std::vector<string*> *lemmas, std::vector<string*> *cpostags, std::vector<string*> *postags, std::vector<string*> *labs, std::vector<vector<string*>*> *feats, std::vector<int> *heads, std::vector<RelationalFeature*> *relFeats){
	init();
	this->forms = forms;
	this->postags = postags;
	this->deprels = labs;
	this->heads = heads;
	this->lemmas = lemmas;
	this->cpostags = cpostags;
	this->feats = feats;
	this->relFeats = relFeats;
}

void DependencyInstance::setFeatureVector(FeatureVector *fv){
	this->fv = fv;
}

int DependencyInstance::length(){
	return (int)(forms->size());
}

string* DependencyInstance::toString(){
	string tmp = string("[");
	string* sb = pool->get(tmp);
	vector<string*>::iterator iter;
	for(iter = forms->begin(); iter != forms->end(); iter++){
		if(iter != forms->begin()){
			sb->append(", ");
		}
		string* s = *iter;
		sb->append(*s);
	}
	sb->append("]\n");
	return sb;
}

DependencyInstance::~DependencyInstance(){
	if(fv != NULL){
		delete(fv);
	}
	if(actParserTree != NULL){
		pool->push_back(actParserTree);
	}

	vector<string*>::iterator iter;
	for(iter = forms->begin(); iter != forms->end(); ++iter){
		pool->push_back(*iter);
	}
	delete(forms);

	for(iter = lemmas->begin(); iter != lemmas->end(); ++iter){
		pool->push_back(*iter);
	}
	delete(lemmas);

	for(iter = cpostags->begin(); iter != cpostags->end(); ++iter){
		pool->push_back(*iter);
	}
	delete(cpostags);
	
	for(iter = postags->begin(); iter != postags->end(); ++iter){
		pool->push_back(*iter);
	}
	delete(postags);

	delete(heads);

	
	for(iter = deprels->begin(); iter != deprels->end(); ++iter){
		pool->push_back(*iter);
	}
	delete(deprels);
	

	vector<vector<string*>*>::iterator iter1;
	for(iter1 = feats->begin(); iter1 !=feats->end(); iter1++){
		for(iter = (*iter1)->begin(); iter != (*iter1)->end(); iter++){
			pool->push_back(*iter);
		}
		delete(*iter1);
	}
	delete(feats);

	vector<RelationalFeature*>::iterator iter2;
	for(iter2 = relFeats->begin(); iter2 != relFeats->end(); iter2++){
		delete(*iter2);
	}
	delete(relFeats);

	fv = NULL;
	actParserTree = NULL;
	forms = NULL;
	lemmas = NULL;
	cpostags = NULL;
	postags = NULL;
	feats = NULL;
	heads = NULL;
	deprels = NULL;
	relFeats = NULL;
}

void DependencyInstance::writeObject(ObjectWriter &out){
	out.writeVector(*forms);
	out.writeVector(*lemmas);
	out.writeVector(*cpostags);
	out.writeVector(*postags);
	out.writeVector(*heads);
	out.writeVector(*deprels);
	out.writeString(actParserTree);
	out.writeVector(*feats);
	vector<RelationalFeature*>::iterator iter;
	for(iter = relFeats->begin(); iter != relFeats->end(); ++iter){
		(*iter)->writeObject(out);
	}
	string s("$end5");
	out.writeString(&s);
}

void DependencyInstance::readObject(ObjectReader &in){
	in.readVector(*forms);
	in.readVector(*lemmas);
	in.readVector(*cpostags);
	in.readVector(*postags);
	in.readVector(*heads);
	in.readVector(*deprels);
	actParserTree = in.readString();
	in.readVector(*feats);
	if(relFeats != NULL){
		vector<RelationalFeature*>::iterator iter;
		for(iter = relFeats->begin(); iter != relFeats->end(); iter++){
			delete(*iter);
		}
		delete(relFeats);
	}
	relFeats = new vector<RelationalFeature*>();
	bool p;
	do{
		RelationalFeature* rf = new RelationalFeature();
		p = rf->readObject(in);
		if(p){
			relFeats->push_back(rf);
		}
		else{
			delete(rf);
		}
	}while(p);
}
